package com.bilibili.juc.locks;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName: ReEntryLockDemo2
 * @Author: Donnie
 * @Date: 2022/7/3 00:30
 * @Description: Reentrant Demo2
 */
public class ReEntryLockDemo2 {
    public synchronized void m1()
    {
        //指的是可重复可递归调用的锁，在外层使用锁之后，在内层仍然可以使用，并且不发生死锁，这样的锁就叫做可重入锁。
        System.out.println(Thread.currentThread().getName()+"\t ----come in");
        m2();
        System.out.println(Thread.currentThread().getName()+"\t ----end m1");
    }
    public synchronized void m2()
    {
        System.out.println(Thread.currentThread().getName()+"\t ----come in");
        m3();
    }
    public synchronized void m3()
    {
        System.out.println(Thread.currentThread().getName()+"\t ----come in");
    }

    static Lock lock = new ReentrantLock();

    public static void main(String[] args)
    {
        /*ReEntryLockDemo reEntryLockDemo = new ReEntryLockDemo();

        new Thread(() -> {
            reEntryLockDemo.m1();
        },"t1").start();*/

        new Thread(() -> {
            for(int i=0;i<20;i++){
                lock.lock();
                try
                {
                    System.out.println(Thread.currentThread().getName()+"\t 11111----come in外层调用");
                    lock.lock();
                    try
                    {
                        System.out.println(Thread.currentThread().getName()+"\t 1111----come in内层调用");
                    }finally {
                        lock.unlock();
                    }
                }finally {
                    lock.unlock();
                }

            }
        },"t1").start();

        new Thread(() -> {
            for(int i=0;i<20;i++){
                lock.lock();
                try
                {
                    System.out.println(Thread.currentThread().getName()+"\t 22222----come in外层调用");
                    lock.lock();
                    try
                    {
                        System.out.println(Thread.currentThread().getName()+"\t 22222----come in内层调用");
                    }finally {
                        lock.unlock();
                    }
                }finally {
                    lock.unlock();
                }

            }
        },"t2").start();


    }

    private static void reEntryM1()
    {
        final Object object = new Object();

        new Thread(() -> {
            synchronized (object){
                System.out.println(Thread.currentThread().getName()+"\t ----外层调用");
                synchronized (object){
                    System.out.println(Thread.currentThread().getName()+"\t ----中层调用");
                    synchronized (object){
                        System.out.println(Thread.currentThread().getName()+"\t ----内层调用");
                    }
                }
            }
        },"t1").start();
    }
}
